package tr.edu.metu.is.mega.client.schedule;

import java.util.ArrayList;
import java.util.List;

import tr.edu.metu.is.mega.client.core.DialogCallbackAdapter;
import tr.edu.metu.is.mega.client.core.MegaUtil;
import tr.edu.metu.is.mega.client.resource.MEGAIconBundle;
import tr.edu.metu.is.mega.client.resource.MEGAResourceBundle;
import tr.edu.metu.is.mega.client.resource.MEGAResources;
import tr.edu.metu.is.mega.common.dto.ActivityTemplateDTO;

import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelFactory;
import com.extjs.gxt.ui.client.data.BeanModelLookup;
import com.extjs.gxt.ui.client.dnd.DND.Feedback;
import com.extjs.gxt.ui.client.dnd.GridDragSource;
import com.extjs.gxt.ui.client.dnd.GridDropTarget;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.FieldSet;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.RowNumberer;
import com.extjs.gxt.ui.client.widget.layout.FillLayout;
import com.extjs.gxt.ui.client.widget.tips.ToolTipConfig;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.AbstractImagePrototype;

/**
 * Panel for activity template management.
 */
public class ActivityTemplatePanel extends LayoutContainer {

    private final MEGAResourceBundle resourceBundle = MEGAResources.RESOURCEBUNDLE;

    private final MEGAIconBundle iconBundle = MEGAResources.ICONBUNDLE;

    private Grid<BeanModel> grid;

    private final BeanModelFactory beanModelFactory;

    /**
     * Default constructor.
     */
    public ActivityTemplatePanel() {
        beanModelFactory = BeanModelLookup.get().getFactory(ActivityTemplateDTO.class);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onRender(Element parent, int pos) {
        super.onRender(parent, pos);
        setLayout(new FillLayout());

        FieldSet set = new FieldSet();
        set.setLayout(new FillLayout());
        set.setHeight(400);
        set.setHeading(resourceBundle.activityTemplateHeading());
        ContentPanel panel = new ContentPanel();
        panel.setHeaderVisible(false);

        panel.add(getGrid());

        panel.setTopComponent(getToolBar());

        set.add(panel);

        add(set);

    }

    /**
     * Initializes and returns toolbar.
     * 
     * @return toolbar
     */
    private ToolBar getToolBar() {
        ToolBar toolBar = new ToolBar();
        toolBar.setMinButtonWidth(70);
        toolBar.setSpacing(5);

        Button addButton = new Button(resourceBundle.add(), AbstractImagePrototype.create(iconBundle.add()));
        addButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent ce) {
                ActivityTemplateDialog dialog = new ActivityTemplateDialog();
                ActivityTemplateDTO dto = new ActivityTemplateDTO();
                dialog.create(dto, new DialogCallbackAdapter<ActivityTemplateDTO>() {

                    @Override
                    public void onOk(ActivityTemplateDTO param) {
                        grid.getStore().add(beanModelFactory.createModel(param));
                    }
                });

            }
        });

        Button updateButton = new Button(resourceBundle.update(), AbstractImagePrototype.create(iconBundle.update()));
        updateButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent ce) {
                if (grid.getSelectionModel().getSelectedItem() != null) {
                    ActivityTemplateDialog dialog = new ActivityTemplateDialog();
                    ActivityTemplateDTO dto = grid.getSelectionModel().getSelectedItem().getBean();
                    dialog.update(dto, new DialogCallbackAdapter<ActivityTemplateDTO>() {

                        @Override
                        public void onOk(ActivityTemplateDTO param) {
                            grid.getStore().update(beanModelFactory.createModel(param));
                        }
                    });
                }

            }
        });

        Button deleteButton = new Button(resourceBundle.delete(), AbstractImagePrototype.create(iconBundle.delete()));
        deleteButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent ce) {
                if (grid.getSelectionModel().getSelectedItem() != null) {
                    grid.getStore().remove(grid.getSelectionModel().getSelectedItem());
                }
            }
        });

        toolBar.add(addButton);
        toolBar.add(updateButton);
        toolBar.add(deleteButton);

        return toolBar;
    }

    /**
     * Returns activity grid.
     * 
     * @return grid activity grid
     */
    private Grid<BeanModel> getGrid() {
        if (grid == null) {

            ListStore<BeanModel> store = new ListStore<BeanModel>();
            RowNumberer rowNumberer = new RowNumberer();
            rowNumberer.setHeader(resourceBundle.activityTemplateSequence());
            rowNumberer.setWidth(150);
            rowNumberer.setId(ActivityTemplateDTO.FIELD_SEQUENCENO);
            List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
            columns.add(rowNumberer);
            columns.add(new ColumnConfig(ActivityTemplateDTO.FIELD_SUBMISSIONTYPE, resourceBundle.activityTemplateType(), 75));
            columns.add(new ColumnConfig(ActivityTemplateDTO.FIELD_DUEDATE, resourceBundle.activityTemplateDueDate(), 150));
            columns.add(new ColumnConfig(ActivityTemplateDTO.FIELD_DUETIME, resourceBundle.activityTemplateDueTime(), 150));
            columns.add(new ColumnConfig(ActivityTemplateDTO.FIELD_ALERT_TIME, resourceBundle.activityTemplateAlertTime(), 150));
            columns.add(new ColumnConfig(ActivityTemplateDTO.FIELD_DESCRIPTION, resourceBundle.activityTemplateDescription(), 150));

            ColumnModel cm = new ColumnModel(columns);

            grid = new Grid<BeanModel>(store, cm);

            grid.addPlugin(rowNumberer);

            new GridDragSource(grid);

            GridDropTarget target = new GridDropTarget(grid);
            target.setAllowSelfAsSource(true);
            target.setFeedback(Feedback.INSERT);

            MegaUtil.decoradeGridViewWithAutoHeight(grid, true);
            ToolTipConfig config = new ToolTipConfig();
            config.setTitle("Ordering");
            config.setText("Drag & Drop a row to reorder");
            config.setMouseOffset(new int[] { 0, 0 });
            config.setAnchor("left");
            grid.setToolTip(config);

        }
        return grid;
    }

    /**
     * Adds activities to grid
     * 
     * @param activityList
     */
    public void setActivities(List<ActivityTemplateDTO> activityList) {
        grid.getStore().removeAll();
        for (ActivityTemplateDTO activity : activityList) {
            grid.getStore().add(beanModelFactory.createModel(activity));
        }
    }

    /**
     * Gets activities from grid.
     * 
     * @return list of activities
     */
    public List<ActivityTemplateDTO> getActivities() {
        List<ActivityTemplateDTO> activities = new ArrayList<ActivityTemplateDTO>(grid.getStore().getModels().size());
        int i = 0;
        for (BeanModel model : grid.getStore().getModels()) {
            ActivityTemplateDTO activity = (ActivityTemplateDTO) model.getBean();
            activity.setSequenceNo(++i);
            activities.add(activity);
        }
        return activities;
    }

    /**
     * Clears gui.
     */
    public void clear() {
        grid.getStore().removeAll();
    }

}
